<?php

  class Date {
    
    private $_type;
    private $_time;
    private $_timestamp;
    static $patterns = array(  # Date patterns set-up
                              'Y' => '([0-9]{4})',
                              'm' => '(0[0-9]|1[0-2])',
                              'd' => '(0[0-9]|[12][0-9]|3[01])',
                              'H' => '([01][0-9]|2[0-3])',
                              'i' => '([0-5][0-9])',
                              's' => '([0-5][0-9])'
                              );
    
    public function __construct($time = 'datetime') {
      switch ($time) {
        case 'datetime':
          $time = date("Y-m-d H:i:s");
          break;
        case 'date':
          $time = date("Y-m-d");
          break;
        case 'time':
          $time = date("H:i:s");
          break;
        case 'timestamp':
          $time = time();
          break;
      }
      $this->_set_basics($time);
    }
    
    private function _set_basics($time) {
      if (strval($time) == '') {
        $time = 0;
      }
      $p = self::$patterns;      if  (is_array($time)) {        $type = 'datetime';        $timestamp = mktime($time['hour'], $time['minute'], $time['second'], $time['month'], $time['day'], $time['year']);        $time = date("Y-m-d H:i:s", $timestamp);              } elseif (preg_match("/^{$p['Y']}[-\/]{$p['m']}[-\/]{$p['d']} {$p['H']}:{$p['i']}(:{$p['s']})?$/", $time, $m)) {
        $type = 'datetime';
        $timestamp = mktime($m[4], $m[5], $m[7], $m[2], $m[3], $m[1]);        
      } elseif (preg_match("/^{$p['d']}[-\/]{$p['m']}[-\/]{$p['Y']}$/", $time, $m)) {
        $type = 'date';
        $timestamp = mktime(0, 0, 0, $m[2], $m[1], $m[3]);        
      } elseif (preg_match("/^{$p['Y']}[-\/]{$p['m']}[-\/]{$p['d']}$/", $time, $m)) {
        $type = 'date';
        $timestamp = mktime(0, 0, 0, $m[2], $m[3], $m[1]);        
      } elseif (preg_match("/^{$p['H']}:{$p['i']}(:{$p['s']})?$/", $time, $m)) {
        $type = 'time';
        $timestamp = mktime($m[1], $m[2], $m[4]);        
      } elseif (strval(intval($time)) == $time) {
        $type = 'timestamp';
        $timestamp = $time;        
      } else {
        logger()->err("Incorrect data type for date construct!");
      }            $this->_time = strval($time);      $this->_type = $type;
      $this->_timestamp = $timestamp;
    }
    
    private function convert_to($type) {
      $obj = new Date($this->_timestamp);
      switch ($type) {
        default:
            $obj->_type = $type;
        case 'datetime':
            $obj->_time = date("Y-m-d H:i:s", $this->_timestamp);
          break;
        case 'date':
            $obj->_time = date("Y-m-d", $this->_timestamp);
          break;
        case 'time':
            $obj->_time = date("H:i:s", $this->_timestamp);
          break;
        case 'timestamp':
            $obj->_time = strval($this->_timestamp);
          break;
      }
      return $obj;
    }
    
    public function to_datetime() {
      return $this->convert_to('datetime');
    }
    
    public function to_date() {
      return $this->convert_to('date');
    }
    
    public function to_time() {
      return $this->convert_to('time');
    }
    
    public function to_timestamp() {
      return $this->convert_to('timestamp');
    }
    
    public function date_format ($format) {
      return strftime($format, $this->_timestamp);
    }        public function from_now () {      $difference = time() - $this->_timestamp;            $s = 1;      $m = 60 * $s;      $h = 60 * $m;      $d = 24 * $h;      $w = 60 * $d;            if ($difference > 0) {        if ($difference < (1 * $m)) {          $str = intval($difference / $s) . " seconds ago";        } elseif ($difference < (1 * $h)) {          $str = intval($difference / $m) . " minutes ago";        } elseif ($difference < (2 * $h)) {          $str = "about hour ago";        } elseif ($difference < (1 * $d)) {          $str = intval($difference / $h) . " hours ago";        } elseif ($difference < (2 * $d)) {          $str = "yesterday";        } else {          $str = intval($difference / $d). " days ago";        }      } else {        $difference = -$difference;        if ($difference < (1 * $m)) {          $str = "in " . intval($difference / $s) . " seconds";        } elseif ($difference < (1 * $h)) {          $str = "in " . intval($difference / $m) . " minutes";        } elseif ($difference < (2 * $h)) {          $str = "in about hour";        } elseif ($difference < (1 * $d)) {          $str = "in " . intval($difference / $h) . " hours";        } elseif ($difference < (2 * $d)) {          $str = "tomorrow";        } else {          $str = "in " . intval($difference / $d). " days";        }      }      return $str;                }
    
    
    
    
    
    public function __toString() {
      return $this->_time;
    }
  
  }
  
?>